package com.bsj.media.network.udpUntil;

import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import com.bsj.media.init.Gb28181RtpCachedThread;
import com.bsj.media.init.SendChannelUntil;
import com.bsj.media.media.gb28181.Gb28181Rtp;
import com.bsj.media.tool.cmd.CmdReqString;
import com.bsj.power.common.def.protocol.gb28181.RtpData;
import com.bsj.power.common.def.protocol.rtp.RTPInfo;
import com.bsj.power.common.util.Conv;
import com.bsj.power.common.util.SsrcUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Objects;

//import com.bsj.media.init.websocket.AudioDataSessionHandle;

/**
 * @author yinhao
 * @version 1.0
 * @description gb28181视频直播流解析
 * @date 2024/6/18
 */
@Slf4j
@ChannelHandler.Sharable
public class UDPRTPHandle extends SimpleChannelInboundHandler<DatagramPacket> {

    // 连接
    static private ChannelHandlerContext myCtx;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket datagramPacket) throws Exception {
        //连接信息
        InetSocketAddress socketAddr = datagramPacket.sender();
        // 数据包信息
        ByteBuf in = datagramPacket.content();
        // 有多少字节可读
        int len = in.readableBytes();
        // 转为数组
        byte[] rtpData = new byte[len];
        in.getBytes(in.readerIndex(), rtpData);
//        log.info("UDP: {}", HexStr.toStr(rtpData));
        // 获取ssrc 并解析ssrc里面信息
        long ssrc = Conv.getIntNetOrder(rtpData, 8);
        // 完整10位ssrc信息
        String completeSsrc = SsrcUtil.formatInt(ssrc);
        //第一位标识直播还是回放
        boolean isReadVideo = Integer.parseInt(completeSsrc.substring(0, 1)) == 0 ? true : false;
        //设备ID
        String vehicleId = Integer.parseInt(completeSsrc.substring(1, 7)) + "";
        //通道号
        int channel = Integer.parseInt(completeSsrc.substring(7));
        // 处理rtp流，输出整帧信息
        int chn = isReadVideo ? channel : channel + 126;
        String key = StrUtil.format("{}_{}", vehicleId, chn);
        List<RtpData> rtpDataAnalysis = Gb28181RtpCachedThread.getMap().computeIfAbsent(key, k -> {
            log.info(StrUtil.format("创建直播GB28181 RTP Data解析, terminalNo={}, chn={}", vehicleId, chn));
            return new Gb28181Rtp(vehicleId, chn);
        }).analysisData(rtpData);
        // 为null，所有解析异常，或者不是完整包
        if (Objects.isNull(rtpDataAnalysis) || rtpDataAnalysis.size() <= 0) {
            return;
        }
        for (RtpData dataAnalysis : rtpDataAnalysis) {
            RTPInfo rtpInfo = new RTPInfo(dataAnalysis);
            String sim = rtpInfo.getSim();
            int channelNo = rtpInfo.getChannelNo();
//            if (vehicleId.equalsIgnoreCase("179")) {
//                FileWriter writer = new FileWriter("/soft/decode/179.h264");
//                writer.write(dataAnalysis.getData(), 0, dataAnalysis.getData().length, true);
//            }
            //如果是对讲
            if (channelNo == CmdReqString.INTERCOM_CHANNEL_NO) {
//                NettyIntercomUntil.push(sim, ctx);
//                AudioDataSessionHandle.pushData(rtpInfo, sim);
            } else {
                SendChannelUntil.pushRTPData(rtpInfo, null);
            }
        }
    }

    public static ChannelHandlerContext getMyCtx() {
        return myCtx;
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 不能关闭!!!若关闭了就意味着将UDP关掉，通信结束。
        System.err.println("UDP error：" + cause.getLocalizedMessage());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        myCtx = ctx;
    }
}
